
const Root = {
    dataToolKits(){
        return JSON.parse($('#dataToolkits').val());
    },
    elCanvas:document.getElementById('canvas'),
    elAttrbar:document.getElementById('attrbar'),
    elToolkit:$('#tookbox').children(),
    //canvas里所有dom的json
    canvasDoms:[],
    //canvas里所有的控件
    canvasCtrls:[],
    //激活的控件
    activeDom:void 0,
    colpick:{
        x:0,y:0,
        activeCtrl:void 0,
        header:$('.color-picker-wrapper').children('.header'),
        wrapper:$(".color-picker-wrapper"),
        picker:$('#colorPicker').colpick({
            flat:true,
            layout:'hex',
            submit:1,
            onSubmit(e){
                Root.colpick.activeCtrl.css.value = "#" + $.colpick.hsbToHex(e);
                Root.colpick.activeCtrl.input.setAttribute("style",`background-color:#${$.colpick.hsbToHex(e)}`);
                Root.SetElementStyles(Root.colpick.activeCtrl.data.el,Root.colpick.activeCtrl.data)
                Root.colpick.wrapper.removeClass("active");
            }
        })
    },
    mounted(){
        $(window).on('click',e=>{
            //判断是不是点击在属性栏
            if(!this.elAttrbar.hasChild(e.target)){
                _.forEach(this.canvasCtrls,tag=>{
                    _.removeClass(tag,"editting")
                })
                this.activeDom =void 0;
            }
        })
        $(this.colpick.header).bind("mousedown",e=>{
            $(window).bind("mousemove",colPickMove)
            $(window).bind("mouseup",colPickStop)
            var self = this;
            var objX = e.pageX,objY = e.pageY;
            function colPickMove(e){
                if(objX-e.pageX<0){
                    self.colpick.x = self.colpick.x + Math.abs(objX - e.pageX);
                }else{
                    self.colpick.x = self.colpick.x - Math.abs(objX - e.pageX);
                }
                if(objY-e.pageY<0){
                    self.colpick.y = self.colpick.y + Math.abs(objY- e.pageY);
                }else{
                    self.colpick.y = self.colpick.y - Math.abs(objY- e.pageY);
                }
                self.colpick.wrapper.css("transform",`translateX(${self.colpick.x}px) translateY(${self.colpick.y}px)`)
                objX = e.pageX;
                objY = e.pageY;
            }
            function colPickStop(){
                $(window).unbind("mousemove",colPickMove)
                $(window).bind("mouseup",colPickStop)
            }
        })
        
    },
    MouseDown(ctrlIndex){
        var self = this;
        var targetTool = $(self.elToolkit[ctrlIndex]);
        //激活当前took
        targetTool.addClass("active")
        //缓存该画布下的所有子元素
        var childrens = this.elCanvas.children;
        $(window).bind("mousemove",move)
        $(window).bind("mouseup",end)

        function move(e){
            //先去掉calss
            _.removeClass(self.elCanvas,"dragging")
            _.forEach(childrens,children=> {
                _.removeClass(children,"dragging")
            });
            //如果在画布里就加上class
            if(self.elCanvas.hasChild(e.target)){
                if(_.hasClass(e.target,'layer-2')){
                    _.addClass(e.target.parentNode,"dragging")
                }else{
                    _.addClass(e.target,"dragging")
                }
                
            }
        }
        function end(e){
            if(self.elCanvas.hasChild(e.target)){
                //异步执行数据处理之后绘图
                setTimeout(()=>{
                    //表示是一级还是二级的tool
                    var flag = true;
                    const uuid = Math.random().toString(16).substring(2);
                    //要判断是不是在二级里面释放鼠标的
                    if(_.hasClass(e.target,'layer-2')){
                        e.target = e.target.parentNode;
                    }
                    _.forEach(childrens,(children,i)=>{
                        //json判断是在canvas加还是child加
                        if(children==e.target){
                            flag = false;
                            self.canvasDoms[i].childrens.push(_.deepExtend({
                                uuid:uuid,
                                el:void 0,
                            },self.dataToolKits()[ctrlIndex]))
                        }
                    })
                    if(flag){
                        self.canvasDoms.push(_.deepExtend({
                            uuid:uuid,
                            el:void 0,
                            childrens:[],
                        },self.dataToolKits()[ctrlIndex]))
                    }
                    //开始绘图
                    self.CanvasDraw(uuid);
                },0)
            }
            $(window).unbind("mousemove",move)
            $(window).unbind("mouseup",end)
            targetTool.removeClass("active")
            _.removeClass(self.elCanvas,"dragging")
            _.forEach(childrens,children=>{
                _.removeClass(children,"dragging")
            })
        }
    },
    CanvasDraw(uuid){
        var self = this;
        _.forEach(this.canvasDoms,cvd=>{
            //一级
            parseElement(1,cvd,this.elCanvas)
            //二级
            _.forEach(cvd.childrens,cc=>{
                parseElement(2,cc,cvd.el)
            })
        })
        function parseElement(level,data,parent){
            //如果还没有生成过dom
            if(!data.el){
                let el = document.createElement(data.tag);
                _.addClass(el,'layer-'+level);
                data.name = `${data.name}-${uuid}`;
                _.addClass(el,data.name);
                if(data.class){
                    _.forEach(data.class,c=>{
                        _.addClass(el,c)
                    })
                }
                self.SetElementStyles(el,data)
                //处理文字
                if(data.inner){
                    el.innerText = data.inner;
                    if(data.editable==true){
                        el.setAttribute("contenteditable","true")
                        $(el).on("input",e=>{
                            data.inner = el.innerText;
                        })
                    }
                }
                data.el = el;
                //添加到控件dom
                self.canvasCtrls.push(el)
                parent.appendChild(el);
                $(el).bind("click",(e)=>{
                    //阻止事件传播给父元素
                    e.stopPropagation();
                    self.activeDom = data;
                    setTimeout(()=>{
                        //生成属性栏
                        self.RegisterEvent(data)
                        _.forEach(self.canvasCtrls,tag=>{
                            _.removeClass(tag,"editting")
                        })
                        _.addClass(el,'editting')
                    },0)
                })
            }
        }
    },
    //生成属性栏
    RegisterEvent(data){
        $(this.elAttrbar).children().remove('.attr-field')
        _.forEach(data.cssDeploy,(css,cssname)=>{
            let label = document.createElement('label');
            _.addClass(label,'attr-field');
            let span = document.createElement('span');
            let input = void 0;
            switch(css.ctrlType){
                case "checkbox":
                    input = document.createElement('a');
                    _.addClass(input,"checkbox")
                    _.forEach(css.options,(val,name)=>{
                        if(name==1&&css.value==val){
                            _.addClass(input,"checked")
                        }
                    })
                    $(input).bind("click",e=>{
                        //设置属性
                        var realValue = void 0;
                        if(_.hasClass(input,"checked")){
                            _.removeClass(input,"checked")
                            realValue = 0;
                        }else{
                            _.addClass(input,"checked")
                            realValue = 1;
                        }
                        _.forEach(css.options,(val,name)=>{
                            if(name==realValue){
                                realValue = val
                            }
                        })
                        css.value = realValue
                        //处理拖动
                        this.DragingMove((realValue=="absolute"),data)
                        this.SetElementStyles(data.el,data)
                    })
                    break;
                case "text":
                    input = document.createElement('input');
                    input.setAttribute("type","text")
                    _.addClass(input,"textbox")
                    input.value = css.value;
                    $(input).bind("input",e=>{
                        //设置属性
                        css.value = e.target.value
                        this.SetElementStyles(data.el,data);
                    })
                    break;
                case "select":
                    input = document.createElement('div');
                    _.addClass(input,"select")
                    var elSelected = document.createElement("span");
                    _.addClass(elSelected,"selected");
                    var elOptions = document.createElement('ul');
                    _.addClass(elOptions,"options");
                    _.addClass(elOptions,"hide");
                    _.forEach(css.options,(value,name)=>{
                        var li = document.createElement("li");
                        if(name==css.value){
                            elSelected.innerText = value;
                        }
                        li.innerText = value;
                        $(li).bind('click',e=>{
                            elSelected.innerText = value;
                            css.value = name;
                            _.addClass(elOptions,"hide");
                            this.SetElementStyles(data.el,data);
                            $(window).unbind("mousedown",clickon);
                        })
                        elOptions.appendChild(li)
                    })
                    $(elSelected).bind('click',(e)=>{
                        _.removeClass(elOptions,"hide")
                        $(window).bind("mousedown",clickon)
                    })
                    input.appendChild(elSelected);
                    input.appendChild(elOptions);
                    function clickon(e){
                        if(!input.hasChild(e.target)){
                            _.addClass(elOptions,"hide")
                            $(window).unbind("mousedown",clickon)
                        }
                    }
                    break;
                case "color":
                    var self = this;
                    input = document.createElement("a")
                    _.addClass(input,"colorpick");
                    input.setAttribute("style",`background-color:${css.value}`);
                    $(input).bind("click",e=>{
                        this.colpick.activeCtrl = {
                            css:css,
                            data:data,
                            input:input
                        };
                        this.colpick.picker.colpickSetColor(css.value);
                        this.colpick.wrapper.addClass("active");
                        $(window).bind("mousedown",colorPickerDown)
                        function colorPickerDown(e){
                            e.stopPropagation();
                            if(!self.colpick.wrapper[0].hasChild(e.target)){
                                self.colpick.activeCtrl = void 0;
                                $(window).unbind("mousedown",colorPickerDown)
                                self.colpick.wrapper.removeClass("active");
                            }
                        }
                    })
                    break;
            }
            label.appendChild(span);
            label.appendChild(input);
            span.innerText = css.name;
            this.elAttrbar.insertBefore(label,this.elAttrbar.children[0]);
        })
    },
    SetElementStyles(el,data){
        var style = "";
        _.forEach(data.css,(value,name)=>{
            style += name +":"+value+";";
        })
        el.setAttribute("style",style)
        style = "."+data.name+"{"
        _.forEach(data.cssDeploy,(val,name)=>{
            style += name +":"+val.value+";";
        })
        style += "}"
        if(!data.elStyle){
            data["elStyle"] = document.createElement("style");
            data.elStyle.setAttribute("type","text/css")
            data.elStyle.setAttribute("id",data.uuid)
            document.head.appendChild(data.elStyle)
        }
        data.elStyle.innerText = style;
    },
    DragingMove(flag,data){
        if(flag){
            _.addClass(data.el,"moving")
            $(data.el).bind("mousedown",down)
        }else{
            _.removeClass(data.el,"moving")
            $(data.el).unbind("mousedown",down)
        }
        var objX = 0,objY = 0;
        function down(e){
            e.stopPropagation();
            objX = e.pageX;
            objY = e.pageY;
            if(!data.css["left"]){
                data.css["left"] = 0;
            }
            if(!data.css["top"]){
                data.css["top"] = 0;
            }
            $(Root.elCanvas).bind("mousemove",move)
            $(window).bind("mouseup",up)
        }
        function move(e){
            e.stopPropagation();
            if(objX-e.pageX<0){
                data.css["left"] = parseInt(data.css["left"]) + Math.abs(objX-e.pageX) +"px";
            }else{
                data.css["left"] = parseInt(data.css["left"]) - Math.abs(objX-e.pageX) +"px";
            }
            if(objY-e.pageY<0){
                data.css["top"] = parseInt(data.css["top"]) + Math.abs(objY-e.pageY) +"px";
            }else{
                data.css["top"] = parseInt(data.css["top"]) - Math.abs(objY-e.pageY) +"px";
            }
            var style = "";
            _.forEach(data.css,(value,name)=>{
                style += name +":"+value+";";
            })
            data.el.setAttribute("style",style)
            objX = e.pageX;
            objY = e.pageY;
        }
        function up(e){
            e.stopPropagation();
            $(Root.elCanvas).unbind("mousemove",move)
            $(window).unbind("mouseup",up)
        }
    },
    RemoveDom(){
        if(this.activeDom){
            this.canvasCtrls = _.filter(this.canvasCtrls,c=>{
                return c!=this.activeDom.el;
            })
            this.canvasDoms = _.filter(this.canvasDoms,c=>{
                c.childrens = _.filter(c.childrens,cc=>{
                    return cc.uuid!=this.activeDom.uuid;
                })
                return c.uuid!=this.activeDom.uuid;
            })
            $("#"+this.activeDom.uuid).remove()
            $(this.activeDom.el).remove()
            this.activeDom = void 0;
            $(this.elAttrbar).children().remove('.attr-field')
        }
        
    },
    Preview(){
        const uuid = Math.random().toString(16).substring(2);
        var root = document.createElement("div");
        root.setAttribute("id","root")
        _.forEach(this.canvasDoms,cd=>{
            var sec = createdElement(1,cd)
            _.forEach(cd.childrens,cdc=>{
                var elc = createdElement(2,cdc)
                sec.appendChild(elc)
            })
            root.appendChild(sec)
        })

        function createdElement(level,cd){
            var el = document.createElement(cd.tag);
            if(cd.class){
                _.forEach(cd.class,c=>{
                    _.addClass(el,c)
                })
            }
            var styles = "";
            _.forEach(cd.css,(value,name)=>{
                styles += name +":"+value+";";
            })
            _.forEach(cd.cssDeploy,(value,name)=>{
                styles += name +":"+value.value+";";
            })
            if(styles!=""){
                el.setAttribute("style",styles)
            }
        
            if(cd.inner){
                el.innerText = cd.inner;
            }
            return el;
        }
        
        $.ajax({
            type:"POST",
            url:"/v1/preview",
            data:JSON.stringify({
                uuid:uuid,
                innerHtml:this.GetFullHtml(root)
            }),
            dataType:"json",
            contentType:"application/json",
            success(res){
                console.log(res)
                window.open(res.url)
            }

        })
    },
    GetFullHtml(root){
        var doc = document.createElement("html")
        doc.innerHTML = `
            <head>
                <title>123123</title>
                <link rel="stylesheet" href="/style.css">
            </head>
            <body>
            </body>`;
        var body = doc.getElementsByTagName("body")[0];
        body.appendChild(root)
        return "<html>"+doc.innerHTML+"</html>";
    }
}

Root.mounted();


